import tkinter as tk
from tkinter import ttk, messagebox
import json
import os
import glob
import requests
import pandas as pd
from io import StringIO
import re

# 读取角色数据
with open('captured_data/roles.json', 'r', encoding='utf-8') as f:
    roles_data = json.load(f)
    # 构建cv_id到cv_name的映射
    cv_id_name_map = {str(role['cv_id']): role['cv_name']
                      for role in roles_data['data']['list'] if 'cv_id' in role}
    cv_id_role_map = {str(role['cv_id']): role['name']
                      for role in roles_data['data']['list'] if 'cv_id' in role}
# 读取章节列表数据
with open('captured_data/chapter_list.json', 'r', encoding='utf-8') as f:
    chapter_list_data = json.load(f)
    # 构建章节ID到标题的映射
    chapter_id_title = {str(chapter['id']): chapter['title']
                        for chapter in chapter_list_data['data']['list']}

# 创建主窗口
root = tk.Tk()
root.title("数据展示界面")
root.state('zoomed')

# 搜索部分
search_frame = tk.Frame(root)
search_frame.pack(padx=10, pady=10, fill=tk.X)

search_label = tk.Label(search_frame, text="搜索角色")
search_label.pack(side=tk.LEFT)

search_entry = tk.Entry(search_frame)
search_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)

# 浮框搜索结果
popup = tk.Toplevel(root)
popup.withdraw()
popup.overrideredirect(True)

result_listbox = tk.Listbox(popup)
result_listbox.pack(fill=tk.BOTH, expand=True)


def select_item(event):
    selection = result_listbox.curselection()
    if selection:
        value = result_listbox.get(selection[0])
        search_entry.delete(0, tk.END)
        search_entry.insert(0, value)
        popup.withdraw()


result_listbox.bind("<Button-1>", select_item)


def update_search_results(event=None):
    keyword = search_entry.get().lower()
    result_listbox.delete(0, tk.END)
    if keyword:
        matches = [name for name in cv_id_name_map.values() if keyword in name.lower()]
        for name in matches:
            result_listbox.insert(tk.END, name)
        x = search_entry.winfo_rootx()
        y = search_entry.winfo_rooty() + search_entry.winfo_height()
        popup.geometry(f"{search_entry.winfo_width()}x200+{x}+{y}")
        popup.deiconify()
    else:
        popup.withdraw()


search_entry.bind("<KeyRelease>", update_search_results)


# 导出未完成章节函数
def export_unfinished():
    try:
        # 收集结果数据
        result_data = []

        # 遍历所有章节详情文件
        for json_file in glob.glob('captured_data/chapter_detail_*.json'):
            with open(json_file, 'r', encoding='utf-8') as f:
                chapter_data = json.load(f)

            # 检查是否有未完成的录音
            data = chapter_data.get('data', {})

            error_lines = data.get('error_lines', [])
            if not error_lines:
                continue  # 没有错误行则跳过

            # 提取章节ID
            chapter_id = os.path.basename(json_file).split('_')[-1].replace('.json', '')
            chapter_title = chapter_id_title.get(chapter_id, f"未知章节({chapter_id})")

            # 获取章节内容文本
            content_url = data.get('chapter_content', {}).get('url', '')
            if not content_url:
                continue

            try:
                # 下载文本内容
                response = requests.get(content_url, timeout=10)
                response.encoding = 'utf-8'
                content_lines = response.text.splitlines()
            except Exception as e:
                print(f"获取章节内容失败 {chapter_id}: {str(e)}")
                continue

            # 处理错误行
            # 处理错误行
            for line_num in error_lines:
                print("==========================")
                print("content_lines:", len(content_lines))
                print("line_num:", int(line_num)-1)
                # 处理错误行
                target_line = None
                    # 查找对应行（支持行号后缀匹配，如 00009 匹配 00238-00009）
                for line in content_lines:
                    if str.__contains__(line, line_num):
                        target_line = line
                        break
                if not target_line:
                    target_line = content_lines[int(line_num) - 1]

                print(f"找到匹配行: {target_line}")

                if not target_line:
                    continue

                # 提取userid
                userid_match = re.search(r'userid="(\d+)"', target_line)
                if not userid_match:
                    continue

                userid = userid_match.group(1)
                cv_name = cv_id_name_map.get(userid, f"未知CV({userid})")
                role_name = cv_id_role_map.get(userid, f"未知角色({userid})")
                # 定义正则表达式模式

                # 提取标签内的文字
                label_text_match = re.search(r'<[^>]*>([^<]+)</[^>]*>', target_line)
                if not label_text_match:
                    continue

                label_text = label_text_match.group(1)

                # 添加到结果
                result_data.append({
                    'cv昵称': cv_name,
                    '角色名称': role_name,
                    '章节ID': chapter_id,
                    '章节标题': chapter_title,
                    '待录台词': label_text
                })

        # 导出到Excel
        if not result_data:
            messagebox.showinfo("提示", "未找到需要处理的未完成章节")
            return

        df = pd.DataFrame(result_data)
        output_path = "未完成章节录音分配.xlsx"
        df.to_excel(output_path, index=False)
        messagebox.showinfo("成功", f"已导出{len(result_data)}条记录到{output_path}")

    except Exception as e:
        messagebox.showerror("错误", f"导出失败: {str(e)}")


# 导出按钮
export_btn = tk.Button(search_frame, text="导出未完成", command=export_unfinished)
export_btn.pack(side=tk.LEFT, padx=5)

# 章节列表表格
chapter_frame = tk.Frame(root)
chapter_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)

chapter_label = tk.Label(chapter_frame, text="章节列表")
chapter_label.pack(anchor=tk.W)

table_frame = tk.Frame(chapter_frame)
table_frame.pack(fill=tk.BOTH, expand=True)

# 滚动条
vscroll = ttk.Scrollbar(table_frame, orient="vertical")
vscroll.pack(side="right", fill="y")

hscroll = ttk.Scrollbar(table_frame, orient="horizontal")
hscroll.pack(side="bottom", fill="x")

# 表格
tree = ttk.Treeview(
    table_frame,
    columns=('标题', '章节语音状态', 'ID'),
    show='headings',
    yscrollcommand=vscroll.set,
    xscrollcommand=hscroll.set
)
tree.column('标题', width=300, stretch=tk.YES)
tree.column('章节语音状态', width=150, stretch=tk.YES)
tree.column('ID', width=100, stretch=tk.YES)

tree.heading('标题', text='标题')
tree.heading('章节语音状态', text='章节语音状态')
tree.heading('ID', text='ID')
tree.pack(side="left", fill=tk.BOTH, expand=True)

vscroll.config(command=tree.yview)
hscroll.config(command=tree.xview)

# 填充表格
for chapter in chapter_list_data['data']['list']:
    tree.insert('', 'end', values=(
        chapter['title'],
        chapter['chapter_voice_status'],
        chapter['id']
    ))


# 窗口大小调整
def on_resize(event):
    table_width = table_frame.winfo_width() - vscroll.winfo_width()
    if table_width > 0:
        tree.column('标题', width=int(table_width * 0.5))
        tree.column('章节语音状态', width=int(table_width * 0.3))
        tree.column('ID', width=int(table_width * 0.2))


root.bind('<Configure>', on_resize)

root.mainloop()